﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Rendiciones.Logica.Enumeradores;
using Rendiciones.Logica.Modelos;
using Rendiciones.Logica.Servicios;
using Rendiciones.Web.infraestructura;
using Tesla.Excepciones;
using Tesla.Validador;

namespace Rendiciones.Web.Custodio
{
    public partial class IngresoRendicion : PageBase
    {
        private static ServGastos _servGastos;
        public Rendicion rendicion;
        private static Validador _validador;
        public List<Proyecto> _proyectos; 

        protected void Page_Load(object sender, EventArgs e)
        {
            Button btnYes = (Button)ctrlAgregarGasto.FindControl("BtnGuardarGasto");
            btnYes.Click += new EventHandler(ctrlAgregarGasto_btnYes_Click);
            Button btnNo = (Button)ctrlAgregarGasto.FindControl("BtnCancelarGasto");
            btnNo.Click += new EventHandler(ctrlAgregarGasto_btnNo_Click);
            if (UsuarioConectado == null) Response.Redirect("~/IniciarSesion.aspx");

            _validador = new Validador();
            _servGastos = new ServGastos();

            if (!IsPostBack)
            {
                hfIdRendicion.Value = (string)Session["RendicionParaCargar"];
                
                var rendicionesPendientes = _servGastos.BuscarRendicionesPendientes(1, UsuarioConectado.IdUsuario, (int)ERol.Custodio);
                if(string.IsNullOrEmpty(hfIdRendicion.Value) && rendicionesPendientes.Count >= 1)
                    MostrarInfo("No se puede ingresar una nueva rendicion mientras tenga una en estado Pendiente","Menu.aspx");

                txtFondoAsignado.Text = UsuarioConectado.SaldoAsignado.ToString();
                txtSaldo.Text = UsuarioConectado.Saldo.ToString();

                Session["datasource"] = null;
                LimpiarErrores(pnlRendicion);
                
                DropDownList1.DataTextField = "Nombre";
                DropDownList1.DataValueField = "IdProyecto";
                CargarCombos();
                CargarGrillaVacia();
                
                if (!string.IsNullOrEmpty(hfIdRendicion.Value))
                {
                    rendicion = _servGastos.CargarRendicionPorId(int.Parse(hfIdRendicion.Value));
                    //rendicion = Modulos.Rendiciones.Gastos.CargarRendicionPorId(int.Parse(rendicionParaCargar));
                    rendicion.DetallesGasto = _servGastos.BuscarGastosDeRendicion(int.Parse(hfIdRendicion.Value));
                    //rendicion.DetallesGasto = Modulos.Rendiciones.Gastos.BuscarGastosDeRendicion(int.Parse(rendicionParaCargar));
                    CargarRendicionSolicitada(rendicion);
                    Session["RendicionParaCargar"] = null;
                }
                else
                {
                    Session["EstadoInicial"] = EEstadoRendicion.PendienteDeEnvio;
                    hfIdRendicion.Value = "0";
                }

            }
        }

        void ctrlAgregarGasto_btnYes_Click(object sender, EventArgs e)
        {
            if(ctrlAgregarGasto.Ingresado)
                CargarGrilla();
        }

        void ctrlAgregarGasto_btnNo_Click(object sender, EventArgs e)
        {
            Session["index"] = null;
        }
        public void CargarCombos()
        {
            _proyectos = _servGastos.TodosLosProyectosAsociados(UsuarioConectado.IdUsuario, ERol.Custodio);
            DropDownList1.DataSource = _proyectos;
            DropDownList1.DataBind();
            //DropDownList1.DataSource = Modulos.Rendiciones.Gastos.TodosLosProyectosAsociados(usuario.IdUsuario);
            txtCentroCosto.Text = _proyectos.First(p => p.IdProyecto == int.Parse(DropDownList1.SelectedItem.Value)).CentroCosto;
            DropDownList1.SelectedIndex = -1;
        }

        public int CalculaSaldo()
        {
            var listadoGastos = (List<Gasto>) Session["datasource"];
            var totalGastos = listadoGastos.Sum(gasto => gasto.TotalPagado);
            var saldoRestante = UsuarioConectado.Saldo - totalGastos;
            return saldoRestante < 0 ? 0 : saldoRestante;
        }

        public int CalculaTotal()
        {
            var listadoGastos = (List<Gasto>)Session["datasource"];
            var totalGastos = listadoGastos.Sum(gasto => gasto.TotalPagado);
            return totalGastos;
        }

        protected void btnGuardarBorrador_Click(object sender, EventArgs e)
        {
            try
            {
                var rendicion = TransformarARendicion();
                Validar(rendicion);
                if (rendicion.Estado == 0)
                    rendicion.Estado = EEstadoRendicion.PendienteDeEnvio;
                _servGastos.IngresarRendicion(ref rendicion);
                
                var idProyecto = int.Parse(DropDownList1.SelectedValue);
                var proyecto = Modulos.Rendiciones.Proyectos.Leer(idProyecto);
                Modulos.Rendiciones.WorkFlows.Entrada(rendicion.IdRendicion, rendicion.Estado, DateTime.Now, proyecto.IdAdministrador, UsuarioConectado.IdUsuario);

                MostrarOk("Rendicion Guardada Satisfactoriamente", "~/Custodio/Menu.aspx");
                //Alert("Rendicion Enviada Satisfactoriamente", this.Page);
                //Response.Redirect("~/Custodio/Menu.aspx");
            }
            catch (ResultadoValidacionException resultadoValidacionException)
            {
                MuestraErroresDeValidacion(pnlRendicion, true, resultadoValidacionException);
            }
        }

        protected void btnEnviar_Click(object sender, EventArgs e)
        {
            try
            {
                var rendicion = TransformarARendicion();
                Validar(rendicion);
                rendicion.Estado = EEstadoRendicion.RevisionDeResponsable;
                _servGastos.IngresarRendicion(ref rendicion);

                
                Modulos.Rendiciones.Usuarios.ActualizaSaldoUsuario(UsuarioConectado.IdUsuario, CalculaSaldo());

                var idProyecto = int.Parse(DropDownList1.SelectedValue);
                var proyecto = Modulos.Rendiciones.Proyectos.Leer(idProyecto);
                Modulos.Rendiciones.WorkFlows.Entrada(rendicion.IdRendicion, rendicion.Estado, DateTime.Now, proyecto.IdAdministrador, UsuarioConectado.IdUsuario);


                //Modulos.Rendiciones.Gastos.IngresarRendicion(rendicion);

                MostrarOk("Rendicion Enviada Satisfactoriamente", "~/Custodio/Menu.aspx");
                //Alert("Rendicion Enviada Satisfactoriamente", this.Page);
                //Response.Redirect("~/Custodio/Menu.aspx");
            }
            catch (ResultadoValidacionException resultadoValidacionException)
            {
                MuestraErroresDeValidacion(pnlRendicion, true, resultadoValidacionException);
            }
            
        }

        public static void Alert(string message, Page page)
        {
            ScriptManager.RegisterStartupScript(page, page.GetType(),
           "err_msg",
           "alert('" + message + "');",
           true);
        }
        
        protected void btnAgregarGasto_Click(object sender, EventArgs e)
        {
            Session["index"] = null;
            ctrlAgregarGasto.NroGasto = CalcularNroGasto();
            ctrlAgregarGasto.Mostrar();
        }

        public string CalcularNroGasto()
        {
            var cantidadGastos = grRendicion.Rows.Count;
            if (cantidadGastos == 0)
                return "1";
            return (cantidadGastos + 1).ToString();
        }

        protected void grRendicion_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            var index = int.Parse(e.CommandArgument.ToString());
            Session["index"] = index;
            if (e.CommandName == "Editar")
            {
                var gastos = (List<Gasto>)Session["datasource"];
                var gasto = gastos[index];
                ctrlAgregarGasto.NroGasto = (index + 1).ToString();
                ctrlAgregarGasto.CargaDatosAPopup(gasto);
            }

            if (e.CommandName == "Eliminar")
            {
                var gastos = (List<Gasto>)Session["datasource"];
                gastos.RemoveAt(index);
                Session["datasource"] = gastos;
                grRendicion.DataSource = gastos;
                grRendicion.DataBind();
                Session["index"] = null;
            }
        }

        protected void grRendicion_SelectedIndexChanged(object sender, EventArgs e)
        {

        }


        private Rendicion TransformarARendicion()
        {
            var rendicion = new Rendicion();

            rendicion.IdProyecto = DropDownList1.SelectedIndex != -1 ? int.Parse(DropDownList1.SelectedValue) : 0;
            rendicion.CentroCosto = txtCentroCosto.Text;
            rendicion.FondoAsignado = !string.IsNullOrEmpty(txtFondoAsignado.Text) ? int.Parse(txtFondoAsignado.Text) : 0;
            rendicion.Saldo = !string.IsNullOrEmpty(txtSaldo.Text) ? int.Parse(txtSaldo.Text) : 0;
            rendicion.DetallesGasto = new List<Gasto>();
            rendicion.GastosAEliminar = new List<Gasto>();
            rendicion.UsuarioIngreso = UsuarioConectado;

            var idRendicion = int.Parse(hfIdRendicion.Value);
            rendicion.IdRendicion = idRendicion != 0 ? idRendicion : rendicion.IdRendicion;
            rendicion.DetallesGasto = (List<Gasto>)Session["datasource"];
            var dtABorrar = (DataTable)Session["dtABorrar"];
            if (dtABorrar != null)
            {
                foreach (DataRow row in dtABorrar.Rows)
                {
                    var nuevoGasto = new Gasto();
                    //nuevoGasto.Archivo = new FileInfo();
                    nuevoGasto.Descripcion = row["Descripcion"].ToString();
                    //nuevoGasto.DvBeneficiario = row["IdProveedor"].ToString();
                    nuevoGasto.FechaDocumento = !string.IsNullOrEmpty(row["FechaDocumento"].ToString()) ? Convert.ToDateTime(row["FechaDocumento"].ToString()) : DateTime.MinValue;
                    nuevoGasto.GastoAsociado = !string.IsNullOrEmpty(row["IdTipoGastoAsoc"].ToString()) ? int.Parse(row["IdTipoGastoAsoc"].ToString()) : 0;
                    nuevoGasto.IdRendicion = !string.IsNullOrEmpty(row["IdRendicion"].ToString()) ? int.Parse(row["IdRendicion"].ToString()) : 0;
                    nuevoGasto.IdGasto = !string.IsNullOrEmpty(row["NroGasto"].ToString()) ? int.Parse(row["NroGasto"].ToString()) : 0;
                    nuevoGasto.Iva = !string.IsNullOrEmpty(row["IVA"].ToString()) ? int.Parse(row["IVA"].ToString()) : 0;
                    nuevoGasto.MontoNeto = !string.IsNullOrEmpty(row["MontoNeto"].ToString()) ? int.Parse(row["MontoNeto"].ToString()) : 0;
                    nuevoGasto.NroDocumento = !string.IsNullOrEmpty(row["NroDocumento"].ToString()) ? int.Parse(row["NroDocumento"].ToString()) : 0;
                    nuevoGasto.NroRendicion = !string.IsNullOrEmpty(row["IdRendicion"].ToString()) ? int.Parse(row["IdRendicion"].ToString()) : 0;
                    nuevoGasto.Retencion = !string.IsNullOrEmpty(row["Retencion"].ToString()) ? int.Parse(row["Retencion"].ToString()) : 0;
                    nuevoGasto.RutBeneficiario = row["RutProveedor"].ToString();
                    nuevoGasto.TipoDocumento = new TipoDocumento { IdDocumento = int.Parse(row["IdTipoDocumento"].ToString()) };
                    nuevoGasto.TipoGasto = new TipoGasto { IdGasto = int.Parse(row["IdTipoGasto"].ToString()) };
                    nuevoGasto.TotalPagado = !string.IsNullOrEmpty(row["TotalPago"].ToString()) ? int.Parse(row["TotalPago"].ToString()) : 0;
                    rendicion.GastosAEliminar.Add(nuevoGasto);
                }
            }
            return rendicion;
        }

        public void CargarRendicionSolicitada(Rendicion rendicion)
        {
            hfIdRendicion.Value = rendicion.IdRendicion.ToString();
            Session["datasource"] = rendicion.DetallesGasto;
            DropDownList1.SelectedIndex = rendicion.IdProyecto;
            txtCentroCosto.Text = rendicion.CentroCosto;
            txtFondoAsignado.Text = rendicion.FondoAsignado.ToString();
            txtSaldo.Text = rendicion.Saldo.ToString();

            grRendicion.DataSource = rendicion.DetallesGasto;
            grRendicion.DataBind();

        }

        public void CargarGrillaVacia()
        {
            var gastos = new List<Gasto>();
            grRendicion.DataSource = gastos;
            grRendicion.DataBind();
        }

        public void CargarGrilla()
        {

            var gastosIngresados = (List<Gasto>)Session["datasource"];

            var gastos = new List<Gasto>();
            var gasto = ctrlAgregarGasto.GastoIngresado;
            if (gastosIngresados == null)
            {
                gastos.Add(gasto);
                grRendicion.DataSource = gastos;
                grRendicion.DataBind();
                Session["datasource"] = gastos;
            }
            else
            {

                if (Session["index"] != null)
                {
                    var index = (int)Session["index"];
                    gastosIngresados[index] = gasto;
                }
                else
                {
                    gastosIngresados.Add(gasto);
                }


                grRendicion.DataSource = gastosIngresados;
                grRendicion.DataBind();
                Session["datasource"] = gastosIngresados;

            }
            Session["index"] = null;
            txtSaldo.Text = CalculaSaldo().ToString();
            lblTotalPagado.Text = CalculaTotal().ToString();
        }

        public void Validar(Rendicion rendicion)
        {
            var mensajesDeValidacion = _validador.Valida(rendicion, new Dictionary<string, object>()).ToList();
            if (!_validador.EsValido)
                throw new ResultadoValidacionException("Hay campos incompletos o que deben ser modificados", mensajesDeValidacion);
        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var idProyecto = int.Parse(DropDownList1.SelectedValue);
            var proyecto = Modulos.Rendiciones.Proyectos.Leer(idProyecto);
            txtCentroCosto.Text = proyecto == null ? "" : proyecto.CentroCosto;
        }

    }
}